/*
 * MIT许可证
 *
 * 版权所有 (c) 2025-2035 JacobGreen
 *
 * 特此免费授予获得本软件及相关文档文件（"软件"）副本的任何人不受限制地处置该软件的权利，
 * 包括不限于使用、复制、修改、合并、发布、分发、再许可和/或出售该软件副本，
 * 以及允许被提供该软件的人这样做，须遵守以下条件：
 *
 * 上述版权声明和本许可声明应包含在该软件的所有副本或实质性部分中。
 *
 * 本软件按"原样"提供，不附带任何形式的明示或暗示的保证，
 * 包括但不限于对适销性、特定用途适用性和不侵权的保证。
 * 在任何情况下，作者或版权持有人均不对任何索赔、损害或其他
 * 责任负责，无论是在合同行为、侵权行为或其他方面，
 * 与软件或软件的使用或其他交易有关。
 */

/**
 * filename:main.c
 * description:是主程序入口
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "Log.h"
#include "ArrayList.h"

/**
 * <p>
 * 主程序入口
 * </p>
 *
 * @param argc 参数数量
 * @param argv 参数列表(字符串)
 */
int main(int argc, char *argv[])
{

    printf("========================================\n");
    printf("================ C Core ================\n");
    printf("========================================\n\n");

    // 从命令行参数设置日志合并模式（必须在logInit之前调用）
    setLogMergeFromArgs(argc, argv);

    // 初始化日志系统
    if (!logInit())
    {
        printf("[INFO] [主程序] [日志] - main.c - 日志系统初始化失败。\n");
        fprintf(stderr, "[ERROR] 日志系统初始化失败。\n");
        return EXIT_FAILURE;
    }
    printf("[INFO] [主程序] [日志] - main.c - 日志系统初始化成功。\n");

    // 从命令行参数设置日志级别
    setLogLevelFromArgs(argc, argv);

    LOG_INFO("主程序", "开始", "========================================");
    LOG_INFO("主程序", "开始", "================ C Core ================");
    LOG_INFO("主程序", "开始", "========================================");

    // 初始化
    ArrayList *list = arrayListInit(DEFAULT_CAPACITY);

    printf("\n============= ArrayList 功能演示 =============\n");
    LOG_INFO("ArrayList", "功能演示", "开始演示ArrayList的各项功能");
    
    // 演示数据和辅助函数
    int compareInt(void *a, void *b) {
        return *((int *)a) - *((int *)b);
    }
    
    void printInt(void *data) {
        printf("%d ", *((int *)data));
    }
    
    // 1. 基本添加操作
    printf("\n1. 基本添加操作:");
    LOG_INFO("ArrayList", "基本添加操作", "开始演示添加元素功能");
    for (int i = 0; i < 10; i++) {
        int *val = (int *)malloc(sizeof(int));
        *val = i * 10;
        list->add(list, val);
    }
    
    printf("\n添加元素后: ");
    list->forEach(list, printInt);
    printf("\n列表大小: %d, 容量: %d\n", list->getSize(list), list->getCapacity(list));
    LOG_INFO("ArrayList", "基本添加操作", "添加元素完成，大小: %d, 容量: %d", list->getSize(list), list->getCapacity(list));
    
    // 2. 索引操作演示
    printf("\n2. 索引操作:");
    LOG_INFO("ArrayList", "索引操作", "开始演示索引相关操作功能");
    printf("\n在索引5添加元素55: ");
    LOG_INFO("ArrayList", "索引操作", "在索引5添加元素55");
    int *val55 = (int *)malloc(sizeof(int));
    *val55 = 55;
    list->addIndex(list, 5, val55);
    list->forEach(list, printInt);
    
    printf("\n在开头添加元素-10: ");
    LOG_INFO("ArrayList", "索引操作", "在开头添加元素-10");
    int *valNeg10 = (int *)malloc(sizeof(int));
    *valNeg10 = -10;
    list->addFirst(list, valNeg10);
    list->forEach(list, printInt);
    
    printf("\n在末尾添加元素100: ");
    LOG_INFO("ArrayList", "索引操作", "在末尾添加元素100");
    int *val100 = (int *)malloc(sizeof(int));
    *val100 = 100;
    list->addLast(list, val100);
    list->forEach(list, printInt);
    
    // 3. 元素获取和替换
    printf("\n\n3. 元素获取和替换:");
    LOG_INFO("ArrayList", "元素获取和替换", "开始演示元素获取和替换功能");
    printf("\n索引3的元素: %d", *((int *)list->get(list, 3)));
    LOG_INFO("ArrayList", "元素获取", "索引3的元素值为: %d", *((int *)list->get(list, 3)));
    printf("\n第一个元素: %d", *((int *)list->getFirst(list)));
    LOG_INFO("ArrayList", "元素获取", "第一个元素值为: %d", *((int *)list->getFirst(list)));
    printf("\n最后一个元素: %d\n", *((int *)list->getLast(list)));
    LOG_INFO("ArrayList", "元素获取", "最后一个元素值为: %d", *((int *)list->getLast(list)));
    
    printf("\n替换索引5的元素为500: ");
    LOG_INFO("ArrayList", "元素替换", "替换索引5的元素为500");
    int *val500 = (int *)malloc(sizeof(int));
    *val500 = 500;
    void *oldVal = list->set(list, 5, val500);
    free(oldVal); // 释放被替换的值
    list->forEach(list, printInt);
    
    // 4. 查找和包含操作
    printf("\n\n4. 查找和包含操作:");
    LOG_INFO("ArrayList", "查找和包含操作", "开始演示元素查找和包含判断功能");
    int *searchVal = (int *)malloc(sizeof(int));
    *searchVal = 30;
    printf("\n元素30的索引位置: %d", list->indexOf(list, searchVal, compareInt));
    LOG_INFO("ArrayList", "元素查找", "元素30的索引位置为: %d", list->indexOf(list, searchVal, compareInt));
    
    int *notExists = (int *)malloc(sizeof(int));
    *notExists = 999;
    printf("\n列表是否包含999: %s\n", list->contains(list, notExists, compareInt) ? "是" : "否");
    LOG_INFO("ArrayList", "包含判断", "列表是否包含999: %s", list->contains(list, notExists, compareInt) ? "是" : "否");
    free(notExists);
    free(searchVal);
    
    // 5. 删除操作
    printf("\n5. 删除操作:");
    LOG_INFO("ArrayList", "删除操作", "开始演示元素删除功能");
    printf("\n删除索引2的元素: ");
    LOG_INFO("ArrayList", "删除操作", "删除索引2的元素");
    oldVal = list->removeIndex(list, 2);
    free(oldVal);
    list->forEach(list, printInt);
    
    printf("\n删除第一个元素: ");
    LOG_INFO("ArrayList", "删除操作", "删除第一个元素");
    oldVal = list->removeFirst(list);
    free(oldVal);
    list->forEach(list, printInt);
    
    printf("\n删除最后一个元素: ");
    LOG_INFO("ArrayList", "删除操作", "删除最后一个元素");
    oldVal = list->removeLast(list);
    free(oldVal);
    list->forEach(list, printInt);
    
    // 6. 排序和反转
    printf("\n\n6. 排序和反转:");
    LOG_INFO("ArrayList", "排序和反转", "开始演示列表排序和反转功能");
    printf("\n当前列表: ");
    LOG_INFO("ArrayList", "排序和反转", "显示当前列表内容");
    list->forEach(list, printInt);
    
    printf("\n升序排序: ");
    LOG_INFO("ArrayList", "排序操作", "执行升序排序");
    list->sort(list, 0, compareInt); // 0表示升序
    list->forEach(list, printInt);
    
    printf("\n降序排序: ");
    LOG_INFO("ArrayList", "排序操作", "执行降序排序");
    list->sort(list, 1, compareInt); // 1表示降序
    list->forEach(list, printInt);
    
    printf("\n反转列表: ");
    LOG_INFO("ArrayList", "反转操作", "执行列表反转");
    list->reverse(list);
    list->forEach(list, printInt);
    
    // 7. Split, Group和其他高级功能
    printf("\n\n7. 高级功能:");
    LOG_INFO("ArrayList", "高级功能", "开始演示Split、Group等高级功能");
    
    // 重置列表用于演示split和group
    LOG_INFO("ArrayList", "高级功能", "重置列表以演示split和group功能");
    list->clear(list);
    for (int i = 0; i < 8; i++) {
        int *val = (int *)malloc(sizeof(int));
        *val = i + 1;
        list->add(list, val);
    }
    
    printf("\n重置后的列表: ");
    LOG_INFO("ArrayList", "高级功能", "显示重置后的列表内容");
    list->forEach(list, printInt);
    
    // 演示split功能
    printf("\n在索引3处拆分为两个列表:");
    LOG_INFO("ArrayList", "高级功能", "在索引3处拆分为两个列表");
    ArrayList **splits = list->split(list, 3);
    
    printf("\n列表1: ");
    LOG_INFO("ArrayList", "Split功能", "显示拆分后的第一个子列表");
    splits[0]->forEach(splits[0], printInt);
    
    printf("\n列表2: ");
    LOG_INFO("ArrayList", "Split功能", "显示拆分后的第二个子列表");
    splits[1]->forEach(splits[1], printInt);
    
    // 演示group功能
    int groupByOddEven(void *data) {
        int val = *((int *)data);
        return val % 2; // 0表示偶数，1表示奇数
    }
    
    printf("\n\n按奇偶分组:");
    LOG_INFO("ArrayList", "高级功能", "按奇偶进行分组操作");
    ArrayList **groups = splits[0]->group(splits[0], groupByOddEven);
    
    printf("\n偶数组: ");
    LOG_INFO("ArrayList", "Group功能", "显示偶数组内容");
    groups[0]->forEach(groups[0], printInt);
    
    printf("\n奇数组: ");
    LOG_INFO("ArrayList", "Group功能", "显示奇数组内容");
    groups[1]->forEach(groups[1], printInt);
    
    // 释放分配的内存
    printf("\n\n释放演示过程中创建的临时列表...\n");
    LOG_INFO("ArrayList", "内存管理", "释放演示过程中创建的临时列表");
    arrayListDestroy(groups[0]);
    arrayListDestroy(groups[1]);
    free(groups);
    // 注意：splits[0]就是原始的list，不要释放它
    arrayListDestroy(splits[1]);
    free(splits);
    
    // 8. 清空主列表
    printf("\n清空主列表...\n");
    LOG_INFO("ArrayList", "清空操作", "清空主列表");
    list->clear(list);
    printf("列表是否为空: %s\n", list->isEmpty(list) ? "是" : "否");
    LOG_INFO("ArrayList", "清空操作", "列表是否为空: %s", list->isEmpty(list) ? "是" : "否");

    // 销毁
    arrayListDestroy(list);
    
    printf("\n========================================\n");
    printf("============ C Core Bye-Bye ===========\n");
    printf("========================================\n");
    LOG_INFO("ArrayList", "功能演示", "ArrayList功能演示完成");
    LOG_INFO("主程序", "结束", "========================================");
    LOG_INFO("主程序", "结束", "============ C Core Bye-Bye ============");
    LOG_INFO("主程序", "结束", "========================================");

    // 日志系统退出
    LOG_INFO("主程序", "退出", "程序正常退出");
    // 关闭日志系统
    logClose();

    // 退出
    return 0;
}
